extends RigidBody2D
class_name ActorV

var actorM:ActorM=null
var _targetPos=Vector2()
var _oppent:ActorV=null
var _velocity=Vector2()
var _isDie=false
var _wDic={}
onready var _healthBar=$healthBar
onready var bTree=$BTREE
onready var _playerBrand:PlayerBrand=$playerBrand
onready var _body:Node2D=$body
func start(i_actorM):
	actorM=i_actorM
	BattleManager.addActorV(self)
	actorM.w_hp.onChange(self,'_hp_change')
	actorM.w_lvl.onChange(self,'_lvl_change')
	_wDic.hpRate=W.w2(self,'_wfn_hpRate').onChange(self,'_wc_hpRate')
	if bTree:
		bTree.enable=true


func _wfn_hpRate():
	return clamp(float(actorM.hp)/actorM.max_hp,0,1)
func _wc_hpRate(value,pre):
	if _healthBar:
		_healthBar.value=value
	if _playerBrand:
		_playerBrand.set_health(value)
	
func _hp_change(cur,pre):
	if cur<0:
		die()
func _lvl_change(cur,pre):
	if _playerBrand:
		_playerBrand.set_lvl(cur)
func _getOppents():
	if actorM.camp=='player':
		return BattleManager.getActorsArr('enemy',actorM.regionId)
	elif actorM.camp=='enemy':
		return BattleManager.getActorsArr('player',actorM.regionId)
func _getNearestOppent():
	var oppents=_getOppents() as Array
	var result=null
	var distance=0
	for oppent in oppents:
		if !result:
			result=oppent
			distance=(position-oppent.position).length()
		var d=(position-oppent.position).length()
		if d<distance:
			result=oppent
			distance=d
	return result
var _rotateArr=[PI/4,-PI/4,PI/2,-PI/2]
var _rotateArr2=[-PI/4,PI/4,-PI/2,PI/2]
var _lastMoveRotate=0
func _move(dir:Vector2):
	dir=dir.normalized()*actorM.moveSpeed
	var checkVec=dir.normalized()*50
	var arr=[0,_lastMoveRotate]
	var arr2
	if randf()<0.5:
		arr2=_rotateArr.duplicate()
	else:
		arr2=_rotateArr2.duplicate()
	arr2.erase(_lastMoveRotate)
	arr.append_array(arr2)
	for r in arr:
		if !_checkDirBlock(checkVec.rotated(r)):
			_lastMoveRotate=r
			_velocity=dir.rotated(r)
			return
	_velocity=dir
	
func _checkDirBlock(dir:Vector2):
	var space_state = get_world_2d().direct_space_state
	var result = space_state.intersect_ray(position,position+dir,[self])
	return result

func _integrate_forces(state):
	state.linear_velocity=_velocity
	_velocity=Vector2()
	pass

var _attackTimer=0
func _getAttackInterval():
	return 1.0/(float(actorM.attackSpeed)/100)
func _canAttack():
	return _attackTimer<=0
func _attack():
	if !is_instance_valid(_oppent) || _oppent.actorM.regionId!=actorM.regionId:
		return
	BattleManager.attack(self,_oppent)
	_attackTimer=_getAttackInterval()
	pass
#受到攻击的动画
var _hitAniTimer=0
func hit_ani():
	_hitAniTimer=0.3
func _process(delta):
	if _body:
		if _hitAniTimer>0:
			_body.modulate=Color('f28e8e')
		else:
			_body.modulate=Color.white
	_hitAniTimer-=delta
	pass
func _physics_process(delta):
	_attackTimer-=delta #更新攻击计数

var _serchTimer=0
func task_hasOppent(task):
	if _oppent:
		task.succeed()
	else:
		task.failed()
func task_serchOppent(task):
	var noFinish=task.get_param(0)
	if task.is_init:
		_serchTimer=0
	_serchTimer-=1
	if _serchTimer<=0:
		_serchTimer=int(rand_range(6,9))
		var oppent=_getNearestOppent()
		if oppent:
			_oppent=oppent
			if noFinish!=1:
				task.succeed()
func task_serchOppentInRange(task):
	var noFinish=task.get_param(0)
	if task.is_init:
		_serchTimer=0
	_serchTimer-=1
	if _serchTimer<=0:
		_serchTimer=int(rand_range(6,9))
		var oppent=_getNearestOppent()
		if oppent && (position-oppent.position).length()<=actorM.attackRange:
			_oppent=oppent
			if noFinish!=1:
				task.succeed()
func task_followAndAttackOppent(task):
	if !is_instance_valid(_oppent) || _oppent.actorM.regionId!=actorM.regionId:
		task.failed()
		return
	var attackRange=actorM.attackRange
	var v=_oppent.position-position
	var d=v.length()
	if d<=attackRange:
		if _canAttack():
			_attack()
	else:
		_move(v)
func task_standAndAttackOppent(task):
	if !is_instance_valid(_oppent) || _oppent.actorM.regionId!=actorM.regionId:
		task.failed()
		return
	var attackRange=actorM.attackRange
	var v=_oppent.position-position
	var d=v.length()
	if d<=attackRange:
		if _canAttack():
			_attack()
func die():
	if _isDie:
		return
	_isDie=true
	#如果是敌人，分享经验
	if actorM.type=='enemy':
		BattleManager.shareExp(self)
	dispose()

func dispose():
	for w in _wDic.values():
		w.dispose()
	BattleManager.removeActorV(self)
	queue_free()
